﻿using System;
using System.Net;
using System.IO;

namespace MxitAPI {

    public class ProductIdRequestData {
        public string Url { get; set; }
        public string SessionId { get; set; }
        public string UserName { get; set; }
        public string CaptchaResponse { get; set; }
        public string CountryCode { get; set; }
        public string Locale { get; set; }

        public ProductIdRequestData() {
        }

    }

    /**
     * Registers the client for first time use by a user
     */
    public class GetProductIdHandler : Handler {

       // private static const string version = "5.8.2";
        private const string clientCategory = "Y";
        private const string path = "1";
        private const string brand = "PC";
        private const string model = "MxitPC by Zane";

        private ProductIdRequestData pidRequestData;

        public GetProductIdHandler( ProductIdRequestData pidRequestData ) {
            this.pidRequestData = pidRequestData;
        }

        private string GetPID() {
            TimeSpan ts = ( DateTime.UtcNow - new DateTime( 1970, 1, 1, 0, 0, 0 ) );
            double unixTime = ts.TotalSeconds;

            string webRequestString = 
                pidRequestData.Url + 
                "?type=getpid" +
                "&sessionid=" + pidRequestData.SessionId +
                "&ver=" + ApplicationInfo.Instance.Version +
                "&login=" + pidRequestData.UserName +
                "&cat=" + clientCategory +
                "&chalresp=" + pidRequestData.CaptchaResponse +
                "&cc=" + pidRequestData.CountryCode +
                "&loc=" + pidRequestData.Locale +
                "&path=" + path +
                "&brand=" + brand +
                "&model=" + model;

            HttpWebRequest myHttpWebRequest = ( HttpWebRequest ) WebRequest.Create( webRequestString );

            // Create the proxy information object 
            //WebProxy proxy = new WebProxy( "http://146.230.94.151:8080", true );
            //proxy.Credentials = new NetworkCredential( "", "" );
            //myHttpWebRequest.Proxy = proxy;

            // Sends the HttpWebRequest and waits for the response.            
            HttpWebResponse myHttpWebResponse = ( HttpWebResponse ) myHttpWebRequest.GetResponse();
            // Gets the stream associated with the response.
            Stream receiveStream = myHttpWebResponse.GetResponseStream();

            long cLength = myHttpWebResponse.ContentLength;

            //Console.WriteLine( "\r\nResponse stream received." );
            byte[] responseBytes = new byte[cLength];
            int i = 0;
            while ( i < cLength ) {
                responseBytes[i] = ( byte ) receiveStream.ReadByte(); //readStream.Read());
                ++i;
            }

            string pidResponse = System.Text.ASCIIEncoding.ASCII.GetString( responseBytes );

            myHttpWebResponse.Close();
            receiveStream.Close();

            return pidResponse;
        }

        private void ProcessPID( string pidResponse ) {
            string[] pidArr = pidResponse.Split( ';' );

            ApplicationInfo app = ApplicationInfo.Instance;
            
            // Error code
            app.PIDErrorCode = Int32.Parse( pidArr[0] );

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

            // Wrong answer
            if ( app.PIDErrorCode == 1 ) {
                app.ChallengeData.Captcha = encoding.GetBytes( pidArr[1] );
            }
            // Session expired
            else if ( app.PIDErrorCode == 2 ) {
                if ( pidArr.Length > 2 ) {
                    app.ChallengeData.SessionId = pidArr[1];
                    app.ChallengeData.Captcha = encoding.GetBytes( pidArr[2] );
                }
                else {
                    app.ChallengeData.Captcha = encoding.GetBytes( pidArr[1] );
                }
            }
            // Undefined
            else if ( app.PIDErrorCode == 3 ) {
            }
            // Critical Error
            else if ( app.PIDErrorCode == 4 ) {
            }
            // Internal Error, Country code not available, select another country
            else if ( app.PIDErrorCode == 5 ) {
            }
            // User isn't registered ( and path 0 was specified)
            else if ( app.PIDErrorCode == 6 ) {
                app.ChallengeData.SessionId = pidArr[1];
                app.ChallengeData.Captcha = encoding.GetBytes( pidArr[2] );
            }
            // User is already registered ( and path 1 was specified)
            else if ( app.PIDErrorCode == 7 ) {
                app.ChallengeData.SessionId = pidArr[1];
                app.ChallengeData.Captcha = encoding.GetBytes( pidArr[2] );
            }

            // End method and do not populate the rest of the application data if there is an error
            if ( app.PIDErrorCode != 0 ) {
                return;
            }

            app.ProductId = pidArr[1];
            app.PrimaryTcpConnectionString = pidArr[2];
            app.PrimaryHttpConnectionString = pidArr[3];
            app.DialingCode = pidArr[4];
            app.NationalPrefix = pidArr[5];
            app.InterationalPrefix = pidArr[6];
            app.SecondaryTcpConnectionString = pidArr[7];
            app.SecondaryHttpConnectionString = pidArr[8];
            app.KeepAliveTime = pidArr[9] == "" ? 0 : Int32.Parse( pidArr[9] );
            app.UserName = pidArr[10];
            app.CountryCode = pidArr[11];
            app.Region = pidArr[12];
            app.utf8Disabled = pidArr[13] == "1" ? true : false;


        }


        public override void Execute() {
            string pid = GetPID();
            ProcessPID( pid );

        }


    }
}
